package com.openbravo.pos.payment;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

 public class MPSWebRequest {

        private String mWebServicePath = "";
        private String mWebMethodName = "";
        private String mXMLNamespace = "";
        private int mTimeout = 30000;
        private String[][] mWSParams;

        public void setXMLNamespace(String namespace) {
            mXMLNamespace = namespace.trim();
        }

        /**
         * Set WebMethod name
         *
         * @param webMethodName WebMethod name
         */
        public void setWebMethodName(String webMethodName) {
            mWebMethodName = webMethodName.trim();
        }

        /**
         * Set WebService URL
         *
         * @param webServiceURL SSL WebService URL
         * @throws Exception When WebService URL is not SSL
         */
        public void setWebServiceURL(String webServiceURL) throws Exception {
            webServiceURL = webServiceURL.trim();
            if (webServiceURL.startsWith("https://")) {
                mWebServicePath = webServiceURL;
            } else {
                throw new Exception("WebService URL value must be SSL");
            }
        }

        /**
         * Set request timeout in milliseconds
         *
         * @param timeout Timeout value in milliseconds
         * @throws Exception When timeout value is less than 0
         */
        public void setTimeout(int timeout) throws Exception {
            if (timeout > 0) {
                mTimeout = timeout;
            } else {
                throw new Exception("Timeout value must be greater than 0");
            }
        }

        /**
         * Build SOAP request string
         *
         * @return SOAP wrapped request string
         */
        private String buildSoapRequest() {
            StringBuilder sb = new StringBuilder();
            sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
            sb.append("<soap:Body>");
            sb.append("<" + mWebMethodName + " xmlns=\"" + mXMLNamespace + "\">");

            if (mWSParams != null) {
                for (int t = 0; t < mWSParams.length; t++) {
                    String name = mWSParams[t][0];
                    String data = mWSParams[t][1];
                    sb.append("<" + name + ">" + data + "</" + name + ">");
                }
            }

            sb.append("</" + mWebMethodName + ">");
            sb.append("</soap:Body>");
            sb.append("</soap:Envelope>");
            return sb.toString();
        }

        /**
         * Set WebMethod parameter, overwriting the value of already existing
         * parameter name
         *
         * @param name parameter name
         * @param value parameter value
         */
        public void setParameter(String name, String value) throws Exception {
            int newLen = 0;
            name = name.trim();
            value = value.trim();

            if (name == "tran") {
                value = value.replace("<", "&lt;").replace(">", "&gt;");
            }

            if (mWSParams == null) {
                mWSParams = new String[1][2];
                newLen = mWSParams.length;
            } else {
                newLen = mWSParams.length + 1;
            }

            String[][] newArray = new String[newLen][2];
            for (int i = 0; i < mWSParams.length; i++) {
                if (mWSParams[i][0] == name) {
                    mWSParams[i][1] = value;
                    return;
                }
                newArray[i][0] = mWSParams[i][0];
                newArray[i][1] = mWSParams[i][1];
            }
            newArray[newLen - 1][0] = name;
            newArray[newLen - 1][1] = value;
            mWSParams = newArray;
        }

        /**
         * Send request to WebService
         *
         * @return String content of WebMethod Result
         * @throws Exception On error communicating with WebService
         */
        public String sendRequest() throws Exception {
            String responseData = "";
            boolean error = false;

            try {

                String soap = buildSoapRequest();

                // Open connection
                URL url = new URL(mWebServicePath);
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setRequestMethod("POST");
                conn.setReadTimeout(mTimeout);
                conn.setConnectTimeout(mTimeout);
                conn.setUseCaches(false);
                conn.setDefaultUseCaches(false);
                conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
                conn.setRequestProperty("Content-Length", String.valueOf(soap.length()));
                conn.setRequestProperty("SOAPAction", "\"" + mXMLNamespace + "/" + mWebMethodName + "\"");
                conn.setRequestProperty("Connection", "Close");

                // Send request
                OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
                wr.write(soap);
                wr.flush();
                wr.close();

                int httpResponseCode = conn.getResponseCode();
                BufferedReader rd;
                if (httpResponseCode != 200) {
                    rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
                } else {
                    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                }

                // Receive response
                String responseBuffer = "";
                while ((responseBuffer = rd.readLine()) != null) {
                    responseData += responseBuffer;
                }
                rd.close();

                int start = 0, end = 0;

                if (httpResponseCode != 200) {
                    error = true;
                    String returnparam = "faultstring";
                    if (responseData.indexOf(returnparam) != -1) {
                        start = responseData.indexOf("<" + returnparam + ">")
                                + returnparam.length() + 2;
                        end = responseData.indexOf("</" + returnparam + ">");
                    }
                } else {
                    String returnparam = mWebMethodName + "Result";
                    start = responseData.indexOf("<" + returnparam + ">") + returnparam.length() + 2;
                    end = responseData.indexOf("</" + returnparam + ">");
                }

                //Extract a single return parameter
                responseData = responseData.substring(start, end).replace("&lt;", "<").replace("&gt;", ">");

            } catch (Exception e) {
                throw new Exception("Error: " + e.getMessage());
            }

            if (error) {
                throw new Exception("Error: " + responseData);
            } else {
                return responseData;
            }
        }
    }